use std::sync::Arc;

use log::Metadata;
use serde::Deserialize;
use serde_json::Value;

use crate::{
    HistoryBatchEncodedType, HistoryEncoder, Message, MessageRole, TalktiveKenerlConfig, ToolParm,
    ToolSigBatchEncodedType, ToolSigEncoder,
};

pub enum TalktiveKenerlAns<R>
where
    R: MessageRole,
{
    Message(Message<R>),
    ToolCall(Vec<ToolParm>),
}

pub trait TalktiveKenerl {
    type KenerlConfig: TalktiveKenerlConfig;
    type ToolSigBatchEncodedType: ToolSigBatchEncodedType;
    type HistoryBatchEncodedType: HistoryBatchEncodedType;
    type ToolSigEncoder: ToolSigEncoder<BatchEncodedType = Self::ToolSigBatchEncodedType>;
    type HistoryEncoder: HistoryEncoder<BatchEncodedType = Self::HistoryBatchEncodedType>;
    fn name() -> &'static str;
    fn build(config: &Self::KenerlConfig) -> anyhow::Result<Self>
    where
        Self: Sized;
    fn send(
        &self,
        history: Option<Self::HistoryBatchEncodedType>,
        tools: Option<Arc<Self::ToolSigBatchEncodedType>>,
    ) -> impl std::future::Future<
        Output = anyhow::Result<
            Vec<TalktiveKenerlAns<<Self::HistoryEncoder as HistoryEncoder>::MessageRole>>,
        >,
    > + Send;
    fn stop(&self) -> impl std::future::Future<Output = anyhow::Result<()>> + Send;
}
